package com.newture.lxz.controller;

import com.github.pagehelper.PageInfo;
import com.newture.lxz.config.Config;
import com.newture.lxz.constant.Constant;
import com.newture.lxz.controller.helper.Page;
import com.newture.lxz.controller.helper.Result;
import com.newture.lxz.db.model.LdCourtAddress;
import com.newture.lxz.db.model.LdCourtAddressWithBLOBs;
import com.newture.lxz.errors.AppException;
import com.newture.lxz.errors.Errors;
import com.newture.lxz.generator.output.Column;
import com.newture.lxz.i18n.I18nTranslator;
import com.newture.lxz.services.ICourtAddressSrv;
import com.newture.lxz.util.BeanKit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author xiao.hu
 * @date 2021-09-25
 * @apiNote
 */
@Controller
@RequestMapping("/court-address")
@Validated
public class CourtAddressController {
    Logger logger = LogManager.getLogger(CourtAddressController.class);

    /**
     * 把业务层的 CourtAddressSrv 类注入进来
     * 供 Controller 层使用
     * 与元注释 @Service 配合
     */
    @Autowired
    ICourtAddressSrv courtAddressSrv;

    @Autowired
    private MessageSource messageSource;

    /**
     * 分页查询
     * 可按页数要求返回特定数量的数据集
     * @param pageNum 页数
     * @param name 法院名称
     * @return 统一返回格式
     */
    @GetMapping("/query")
    @ResponseBody
    public Result query(
            @RequestParam(value = Constant.PAGE, defaultValue = "1")Integer pageNum,
            @RequestParam(value = Constant.PAGE_SIZE, defaultValue = Config.PAGE_SIZE + "") Integer pageSize,
            @RequestParam(name = Column.LD_COURT_ADDRESS.COURT_NAME, required = false) String name) {
        /**
         * 打印日志
         */
        logger.debug(String.format("The value of parameter name is %s in %s.()", name, this.getClass().getSimpleName()));

        String[] keysRequired = new String[]{
                Column.ID,
                Column.VERSION,
                Column.LD_COURT_ADDRESS.COURT_NAME,
                Column.LD_COURT_ADDRESS.FIRST_INSTANCE,
                Column.LD_COURT_ADDRESS.SECOND_INSTANCE,
                Column.LD_COURT_ADDRESS.PROVINCE,
                Column.LD_COURT_ADDRESS.PHONE,
                Column.LD_COURT_ADDRESS.ADDRESS,
                Column.LD_COURT_ADDRESS.REMARK
        };

        /**
         * 通过服务层的类对象进行数据集的获取
         */
        PageInfo<LdCourtAddress> pageInfo = courtAddressSrv.query(pageNum, pageSize, name, keysRequired);

        /**
         * 转义数据中的某些字段
         */
        List<LdCourtAddress> itemList = pageInfo.getList();

        List<Map<String, Object>> dataList = new ArrayList<>();
        for(LdCourtAddress t : itemList) {
            Map<String, Object> map = BeanKit.describe(t, keysRequired, (tMap, key, value) -> {
                if(Column.LD_COURT_ADDRESS.FIRST_INSTANCE.equals(key)
                || Column.LD_COURT_ADDRESS.SECOND_INSTANCE.equals(key)) {
                    String escapedValue = I18nTranslator.get((String) value);
                    tMap.put(Constant.ESCAPED_PREFIX + key, escapedValue);
                }
            });

            dataList.add(map);
        }


        Page<Map<String, Object>> mapPage = new Page<> (
                dataList, pageInfo.getPageNum(),
                pageInfo.getPageSize(), pageInfo.getPages(), pageInfo.getTotal());

        /**
         * 得到的数据统一使用 Result 类进行包装
         */
        return Result.success(mapPage);
    }

    /**
     * 找到指定记录的详情
     * @param id
     * @return
     */
    @GetMapping("/item")
    @ResponseBody
    public Result item(@RequestParam(name = Column.ID) Integer id) {
        /**
         * 打印日志
         */
        logger.debug(String.format("The value of parameter id is %s in %s.()",
                id, this.getClass().getSimpleName()));
        /**
         * 通过服务层的类对象进行数据集的获取
         */
        LdCourtAddress item = courtAddressSrv.findById(id, new String[]{
                Column.ID,
                Column.VERSION,
                Column.LD_COURT_ADDRESS.COURT_NAME,
                Column.LD_COURT_ADDRESS.PHONE,
                Column.LD_COURT_ADDRESS.PROVINCE,
                Column.LD_COURT_ADDRESS.FIRST_INSTANCE,
                Column.LD_COURT_ADDRESS.SECOND_INSTANCE,
                Column.LD_COURT_ADDRESS.REMARK,
                Column.LD_COURT_ADDRESS.ADDRESS
        });

        /**
         * 得到的数据统一使用 Result 类进行包装
         */
        return Result.success(item);
    }

    /**
     * 测试统一异常处理
     */
    @GetMapping("/exception")
    @ResponseBody
    public void exception() {
        logger.debug(messageSource.getMessage(Errors.INTERNAL_ERROR.name(), null, Locale.getDefault()));
        throw new AppException(Errors.INTERNAL_ERROR.name(), "No Parameter", "Test exception");
    }

    /**
     * 测试回滚
     */
    @GetMapping("/test-transaction")
    @ResponseBody
    public void testTransaction() {
        List<LdCourtAddressWithBLOBs> list = new ArrayList<>();
        for(int i = 0; i < 3; i++) {
            LdCourtAddressWithBLOBs obj = new LdCourtAddressWithBLOBs() ;
            obj.setProvince("changsha_" + i);
            obj.setCourtName("No.1_" + i);
            obj.setFirstInstance(Constant.YES);
            obj.setSecondInstance(Constant.NO);
            obj.setAddress("shaoshang street_" + i);
            obj.setPhone("123456_" + i);
            list.add(obj);
        }
        courtAddressSrv.batchInsertSelective(list);
    }

    /**
     * 新增数据
     * @param provice
     * @param courtName
     * @param firstInstance
     * @param secondInstance
     * @param address
     * @param phone
     * @param remark
     * @return
     */
    @PostMapping("/add")
    @ResponseBody
    public Result add(
            @RequestParam(name = Column.LD_COURT_ADDRESS.PROVINCE, required = true) String provice,
            @RequestParam(name = Column.LD_COURT_ADDRESS.COURT_NAME, required = true) String courtName,
            @RequestParam(name = Column.LD_COURT_ADDRESS.FIRST_INSTANCE, required = true) String firstInstance,
            @RequestParam(name = Column.LD_COURT_ADDRESS.SECOND_INSTANCE, required = true) String secondInstance,
            @RequestParam(name = Column.LD_COURT_ADDRESS.ADDRESS, required = true) String address,
            @RequestParam(name = Column.LD_COURT_ADDRESS.PHONE, required = true) String phone,
            @RequestParam(name = Column.LD_COURT_ADDRESS.REMARK, required = false) String remark) {
        LdCourtAddressWithBLOBs obj = new LdCourtAddressWithBLOBs() ;
        Date now = new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd'T'HH");
        String gmtCreated = sdf.format(now);
        obj.setGmtModified(gmtCreated);
        obj.setProvince(provice);
        obj.setCourtName(courtName);
        obj.setFirstInstance(firstInstance);
        obj.setSecondInstance(secondInstance);
        obj.setAddress(address);
        obj.setPhone(phone);
        obj.setRemark(remark);
        int id = courtAddressSrv.insert(obj);
        return Result.success(id);
    }

    /**
     *
     * @param formData
     * @return
     */
    @PostMapping("/addByJson")
    @ResponseBody
    public Result add(@RequestBody Map<String, Object> formData) {
        String province = (String) formData.get(Column.LD_COURT_ADDRESS.PROVINCE);
        String courtName = (String) formData.get(Column.LD_COURT_ADDRESS.COURT_NAME);
        String firstInstance = (String) formData.get(Column.LD_COURT_ADDRESS.FIRST_INSTANCE);
        String secondInstance = (String) formData.get(Column.LD_COURT_ADDRESS.SECOND_INSTANCE);
        String address = (String) formData.get(Column.LD_COURT_ADDRESS.ADDRESS);
        String phone = (String) formData.get(Column.LD_COURT_ADDRESS.PHONE);

        LdCourtAddressWithBLOBs obj = new LdCourtAddressWithBLOBs() ;
        obj.setProvince(province);
        obj.setCourtName(courtName);
        obj.setFirstInstance(firstInstance);
        obj.setSecondInstance(secondInstance);
        obj.setAddress(address);
        obj.setPhone(phone);
        int id = courtAddressSrv.insertSelective(obj);
        return Result.success(id);
    }

    /**
     *
     * @param province
     * @param courtName
     * @param firstInstance
     * @param secondInstance
     * @param address
     * @param phone
     * @return
     */
    @PostMapping("/addSelective")
    @ResponseBody
    public Result addSelective(@RequestParam(name = Column.LD_COURT_ADDRESS.PROVINCE) String province,
                      @RequestParam(name = Column.LD_COURT_ADDRESS.COURT_NAME) String courtName,
                      @RequestParam(name = Column.LD_COURT_ADDRESS.FIRST_INSTANCE) String firstInstance,
                      @RequestParam(name = Column.LD_COURT_ADDRESS.SECOND_INSTANCE) String secondInstance,
                      @RequestParam(name = Column.LD_COURT_ADDRESS.ADDRESS) String address,
                      @RequestParam(name = Column.LD_COURT_ADDRESS.PHONE) String phone) {
        LdCourtAddressWithBLOBs obj = new LdCourtAddressWithBLOBs() ;
        obj.setProvince(province);
        obj.setCourtName(courtName);
        obj.setFirstInstance(firstInstance);
        obj.setSecondInstance(secondInstance);
        obj.setAddress(address);
        obj.setPhone(phone);
        int id = courtAddressSrv.insertSelective(obj);
        return Result.success(id);
    }

    /**
     *
     * @param id
     * @param version
     * @param provice
     * @param courtName
     * @param firstInstance
     * @param secondInstance
     * @param address
     * @param phone
     * @return
     */
    @PostMapping("/update")
    @ResponseBody
    public Result update(
            @RequestParam(name = Column.ID, required = true) Integer id,
            @RequestParam(name = Column.VERSION, required = true) Integer version,
            @RequestParam(name = Column.LD_COURT_ADDRESS.PROVINCE) String provice,
            @RequestParam(name = Column.LD_COURT_ADDRESS.COURT_NAME) String courtName,
            @RequestParam(name = Column.LD_COURT_ADDRESS.FIRST_INSTANCE) String firstInstance,
            @RequestParam(name = Column.LD_COURT_ADDRESS.SECOND_INSTANCE) String secondInstance,
            @RequestParam(name = Column.LD_COURT_ADDRESS.ADDRESS) String address,
            @RequestParam(name = Column.LD_COURT_ADDRESS.PHONE) String phone) {
        LdCourtAddressWithBLOBs obj = new LdCourtAddressWithBLOBs() ;
        obj.setProvince(provice);
        obj.setCourtName(courtName);
        obj.setFirstInstance(firstInstance);
        obj.setSecondInstance(secondInstance);
        obj.setAddress(address);
        obj.setPhone(phone);
        courtAddressSrv.update(id, version, obj);
        return Result.success();
    }

    /**
     *
     * @param id
     * @param version
     * @return
     */
    @PostMapping("/remove")
    @ResponseBody
    public Result remove(
            @RequestParam(name = Column.ID) Integer id,
            @RequestParam(name = Column.VERSION) Integer version) {
        courtAddressSrv.remove(id, version);
        return Result.success();
    }



}
